package com.niiwoo.civet.trade.service.dubbo.invest;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSONObject;
import com.niiwoo.activity.stage.dto.request.prize.PrizeAddInterestReqDTO;
import com.niiwoo.activity.stage.dto.request.prize.PrizeAddInterestReqDTO.ProjectPrizeReqDTO;
import com.niiwoo.activity.stage.dto.request.prize.ProjectRaiseAddInterestReqDTO;
import com.niiwoo.activity.stage.dto.request.prize.ProjectRaiseAddInterestReqDTO.ProjectRaisePlanReqDTO;
import com.niiwoo.activity.stage.dto.response.prize.ProjectAddInterestDTO;
import com.niiwoo.activity.stage.dto.response.prize.ProjectAddInterestSummarizeRespDTO;
import com.niiwoo.activity.stage.service.prize.ActivityPrizeDubboService;
import com.niiwoo.civet.account.dto.response.GroupAmountByDayResponseDTO;
import com.niiwoo.civet.account.dto.response.GroupAmountByMonthResponseDTO;
import com.niiwoo.civet.account.enums.GroupUserBillAmountTypeEnum;
import com.niiwoo.civet.account.service.bill.UserBillStatisticsDubboService;
import com.niiwoo.civet.trade.dao.entity.CreditorSaleDetail;
import com.niiwoo.civet.trade.dto.invest.DayAllProjectInvestorPlanDTO;
import com.niiwoo.civet.trade.dto.invest.InvestPlanStatDTO;
import com.niiwoo.civet.trade.dto.request.invest.InvestCalendarRequestDTO;
import com.niiwoo.civet.trade.dto.response.invest.DayInvestInfoResponseDTO;
import com.niiwoo.civet.trade.dto.response.invest.DayInvestOrderInfoDTO;
import com.niiwoo.civet.trade.dto.response.invest.DayInvestorPlanInfoDTO;
import com.niiwoo.civet.trade.dto.response.invest.DayPackageInfoDTO;
import com.niiwoo.civet.trade.dto.response.invest.InvestCalendarDayStatResponseDTO;
import com.niiwoo.civet.trade.dto.response.invest.InvestCalendarMonthStatResponseDTO;
import com.niiwoo.civet.trade.dto.response.invest.MonthEveryDayInvestStatusDTO;
import com.niiwoo.civet.trade.enums.LoanTypeEnum;
import com.niiwoo.civet.trade.service.invest.InvestCalendarDubboService;
import com.niiwoo.civet.trade.service.local.invest.InvestCalendarLocalService;
import com.niiwoo.tripod.base.utils.DateUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * 投资日历dubbo服务
 */
@Slf4j
@Service(version = "1.0.0")
public class InvestCalendarDubboServiceImpl implements InvestCalendarDubboService {

	@Autowired
	private InvestCalendarLocalService investCalendarLocalService;
	@Reference(version = "1.0.0")
	private ActivityPrizeDubboService activityPrizeDubboService;
	@Reference(version = "1.0.0")
	private UserBillStatisticsDubboService userBillStatisticsDubboService;
	
	@Override
	public List<MonthEveryDayInvestStatusDTO> getMonthEveryDayInvestStatus(InvestCalendarRequestDTO request) {
		List<InvestPlanStatDTO> unReceiveList = investCalendarLocalService.findMonthEveryDayUnReceiveInvestPlans(request.getUserId(), request.getBeginDate(), request.getEndDate());
		List<InvestPlanStatDTO> receivedList = investCalendarLocalService.findMonthEveryDayReceivedInvestPlans(request.getUserId(), request.getBeginDate(), request.getEndDate());
		
		Map<String, MonthEveryDayInvestStatusDTO> map = new HashMap<>();
		
		MonthEveryDayInvestStatusDTO statusDTO = null;
		for (InvestPlanStatDTO dto : unReceiveList) {
			statusDTO = new MonthEveryDayInvestStatusDTO();
			statusDTO.setReturnedMoneyDate(dto.getDay());
			statusDTO.setStatus((byte)1);
			map.put(dto.getDay(), statusDTO);
		}
		
		for (InvestPlanStatDTO dto : receivedList) {
			if (map.containsKey(dto.getDay())) continue;
			
			statusDTO = new MonthEveryDayInvestStatusDTO();
			statusDTO.setReturnedMoneyDate(dto.getDay());
			statusDTO.setStatus((byte)2);
			map.put(dto.getDay(), statusDTO);
		}
		
		List<MonthEveryDayInvestStatusDTO> result = new ArrayList<>();
		Iterator<MonthEveryDayInvestStatusDTO> it = map.values().iterator();
		while (it.hasNext()) {
			result.add(it.next());
		}
		
		return result;
	}

	@Override
	public DayInvestInfoResponseDTO getDayInvestInfo(InvestCalendarRequestDTO request) {
		List<DayAllProjectInvestorPlanDTO> list = investCalendarLocalService.getDayAllProjectInvestorPlans(request.getUserId(), request.getBeginDate(), request.getEndDate());
		
		DayInvestInfoResponseDTO result = null;
		
		if (list == null || list.isEmpty()) return result;
		
		//获取所有转让中的债权信息
		List<CreditorSaleDetail> details = investCalendarLocalService.findUserUnderwayCreditorSaleDetail(request.getUserId(), request.getBeginDate(), request.getEndDate());
		Map<String, CreditorSaleDetail> saleDetails = new HashMap<>();
		if (details != null && !details.isEmpty()) {
			for (CreditorSaleDetail detail : details) {
				if (saleDetails.containsKey(String.valueOf(detail.getInvestOrderId()))) continue;
				else saleDetails.put(String.valueOf(detail.getInvestOrderId()), detail);
			}
		}
		
		// 今日待收
		BigDecimal unreceivedAmount = new BigDecimal(0);
		// 今日已收
		BigDecimal receivedAmount = new BigDecimal(0);
		
		List<ProjectRaisePlanReqDTO> raiseList = new ArrayList<>();
		List<ProjectPrizeReqDTO> prizeList = new ArrayList<>();
		ProjectRaisePlanReqDTO projectRaisePlanReqDTO = null;
		ProjectPrizeReqDTO projectPrizeReqDTO = null;
		for (DayAllProjectInvestorPlanDTO plan : list) {
			if (plan.getPrizeId() != null && plan.getPrizeId() > 0) {
				projectPrizeReqDTO = new ProjectPrizeReqDTO();
				projectPrizeReqDTO.setProjectId(plan.getProjectId());
				projectPrizeReqDTO.setPrizeId(plan.getPrizeId());
				projectPrizeReqDTO.setCurrentPeriod(plan.getCurrentPeriod());
				
				prizeList.add(projectPrizeReqDTO);
			}
			projectRaisePlanReqDTO = new ProjectRaisePlanReqDTO();
			projectRaisePlanReqDTO.setInvestOrderId(plan.getInvestOrderId());
			projectRaisePlanReqDTO.setCurrentPeriod(plan.getCurrentPeriod());
			
			raiseList.add(projectRaisePlanReqDTO);
		}
		
		//标的加息
		ProjectRaiseAddInterestReqDTO reqDTO = new ProjectRaiseAddInterestReqDTO();
		reqDTO.setUserId(request.getUserId());
		reqDTO.setInvestOrderList(raiseList);
		ProjectAddInterestSummarizeRespDTO projectAddInterestSummarizeRespDTO = activityPrizeDubboService.findProjectRaiseAddInterestInfo(reqDTO);
		Map<String, ProjectAddInterestDTO> projectRaiseMap = new HashMap<>();
		if (projectAddInterestSummarizeRespDTO != null && projectAddInterestSummarizeRespDTO.getDetails() != null) {
			for (ProjectAddInterestDTO projectRaisePlanDTO : projectAddInterestSummarizeRespDTO.getDetails()) {
				if (projectRaisePlanDTO.getExtraAmount() == null) continue;
				
				projectRaiseMap.put(String.valueOf(projectRaisePlanDTO.getInvestOrderId())+"_"+String.valueOf(projectRaisePlanDTO.getCurrentPeriod()), projectRaisePlanDTO);
			}
		}
		
		//投资加息
		PrizeAddInterestReqDTO prizeReqDTO = new PrizeAddInterestReqDTO();
		prizeReqDTO.setUserId(request.getUserId());
		prizeReqDTO.setBeginDate(request.getBeginDate());
		prizeReqDTO.setEndDate(request.getEndDate());
		prizeReqDTO.setProjectPrizeList(prizeList);
		projectAddInterestSummarizeRespDTO = activityPrizeDubboService.findProjectPrizeAddInterestInfo(prizeReqDTO);
		Map<String, ProjectAddInterestDTO> projectPrizeMap = new HashMap<>();
		if (projectAddInterestSummarizeRespDTO != null && projectAddInterestSummarizeRespDTO.getDetails() != null) {
			for (ProjectAddInterestDTO projectRaisePlanDTO : projectAddInterestSummarizeRespDTO.getDetails()) {
				if (projectRaisePlanDTO.getExtraAmount() == null) continue;
				
				projectPrizeMap.put(projectRaisePlanDTO.getPrizeId()+"_"+projectRaisePlanDTO.getProjectId()+"_"+projectRaisePlanDTO.getCurrentPeriod(), projectRaisePlanDTO);
			}
		}
		
		// 智能投列表
		List<DayPackageInfoDTO> packageOrders = new ArrayList<>();
		// 信用标列表
		List<DayInvestOrderInfoDTO> creditsLoans = new ArrayList<>();
		// 抵押标列表
//		List<DayInvestOrderInfoDTO> mortgageLoans = new ArrayList<>();
		// 债转标列表
		List<DayInvestOrderInfoDTO> debtOrders = new ArrayList<>();
		
		DayInvestorPlanInfoDTO dayInvestorPlanInfoDTO = null;
		DayPackageInfoDTO dayPackageInfoDTO = null;
		DayInvestOrderInfoDTO dayInvestOrderInfoDTO = null;
		
		Map<String, DayPackageInfoDTO> packageOrderMap = new HashMap<>();
		Map<String, DayInvestOrderInfoDTO> investOrderMap = new HashMap<>();
		
		DateTime dt = new DateTime();
		Date now = dt.withHourOfDay(0).withMinuteOfHour(0).withSecondOfMinute(0).withMillisOfSecond(0).toDate();
		for (DayAllProjectInvestorPlanDTO dto : list) {
			//不是债转标且智能投订单ID不为空
			if (dto.getPackageOrderId() != null && !packageOrderMap.containsKey(String.valueOf(dto.getPackageOrderId()))) {
				dayPackageInfoDTO = new DayPackageInfoDTO();
				dayPackageInfoDTO.setPackageTitile(dto.getPackageTitle());
				dayPackageInfoDTO.setStatus((byte) 2);
				dayPackageInfoDTO.setPackageOrderId(String.valueOf(dto.getPackageOrderId()));
				dayPackageInfoDTO.setInvestorPlans(new ArrayList<>());
				
				packageOrderMap.put(String.valueOf(dto.getPackageOrderId()), dayPackageInfoDTO);
			} else {
				if (dto.getPackageOrderId() == null && !investOrderMap.containsKey(String.valueOf(dto.getInvestOrderId()))) {
					dayInvestOrderInfoDTO = new DayInvestOrderInfoDTO();
					dayInvestOrderInfoDTO.setStatus((byte) 2);
					dayInvestOrderInfoDTO.setInvestOrderId(String.valueOf(dto.getInvestOrderId()));
					dayInvestOrderInfoDTO.setInvestorPlans(new ArrayList<>());
					
					investOrderMap.put(String.valueOf(dto.getInvestOrderId()), dayInvestOrderInfoDTO);
				}
			}
				
			dayInvestorPlanInfoDTO = new DayInvestorPlanInfoDTO();
			dayInvestorPlanInfoDTO.setBorrowRate(dto.getBorrowRate());
			dayInvestorPlanInfoDTO.setCurrentPeriod(dto.getCurrentPeriod());
			dayInvestorPlanInfoDTO.setDeadlineUnit(dto.getDeadlineUnit());
			dayInvestorPlanInfoDTO.setInvestOrderId(String.valueOf(dto.getInvestOrderId()));
			dayInvestorPlanInfoDTO.setProjectId(String.valueOf(dto.getProjectId()));
			dayInvestorPlanInfoDTO.setProjectTitile(dto.getProjectTitle());
			dayInvestorPlanInfoDTO.setTotalPeriod(dto.getTotalPeriod());
			dayInvestorPlanInfoDTO.setIsGuarantee(dto.getIsGuarantee());
			
			boolean isOver = false;
			
			//待回款：1-待回款、2-逾期待回款、3-转让中
			//已回款：4-已按时回款、5-已提前结清、6-已提前回款、7-已转让、8-逾期已回款、9-已结清。（其中：已逾期回款=已垫付/借款人逾期还款）
			
			// 收款状态(1未收款，2正常收款，3逾期收款，4提前结清收款，5已转让)
			switch (dto.getReceivedStatus()) {
			case 1: //未收款
				dayInvestorPlanInfoDTO.setUnreceivedAmount(dto.getCapital().add(dto.getInterest()).subtract(dto.getReceivedCapital()).subtract(dto.getReceivedInterest()).setScale(2, RoundingMode.HALF_EVEN));
				unreceivedAmount = unreceivedAmount.add(dto.getCapital()).add(dto.getInterest()).subtract(dto.getReceivedCapital()).subtract(dto.getReceivedInterest()).setScale(2, RoundingMode.HALF_EVEN);
				//防止部分还款
				receivedAmount = receivedAmount.add(dto.getReceivedCapital()).setScale(2, RoundingMode.HALF_EVEN); //.add(dto.getReceivedInterest()).add(dto.getReceivedPenaltyFee())
				
				if (dto.getReceivedDate().before(now)) {
					dayInvestorPlanInfoDTO.setStatus((byte)2); //2-逾期待回款
					dayInvestorPlanInfoDTO.setAdvanceOverdueDays(calcAdvanceOverdueDay(dto.getReceivedDate(), dto.getAdvanceOverdueDays()));
				} else {
					if (saleDetails.containsKey(String.valueOf(dto.getInvestOrderId()))) {
						dayInvestorPlanInfoDTO.setStatus((byte)3); //3-转让中
					} else {
						dayInvestorPlanInfoDTO.setStatus((byte)1); //1-待回款
					}
				}
				
				if (dto.getPackageOrderId() != null && packageOrderMap.containsKey(String.valueOf(dto.getPackageOrderId()))) {
					dayPackageInfoDTO.setStatus((byte) 1);
				} else if (dto.getPackageOrderId() == null && investOrderMap.containsKey(String.valueOf(dto.getInvestOrderId()))) {
					dayInvestOrderInfoDTO.setStatus((byte) 1);
				}
				break;
			case 2: //正常收款
				dayInvestorPlanInfoDTO.setUnreceivedAmount(dto.getReceivedCapital().add(dto.getReceivedInterest()).add(dto.getReceivedPenaltyFee().setScale(2, RoundingMode.HALF_EVEN)));
				receivedAmount = receivedAmount.add(dto.getReceivedCapital()).setScale(2, RoundingMode.HALF_EVEN); //.add(dto.getReceivedInterest()).add(dto.getReceivedPenaltyFee())
				
				// 4-已按时回款、6-已提前回款
				if (dto.getOverTime().before(dto.getReceivedDate())) {
					dayInvestorPlanInfoDTO.setStatus((byte)6); //6-已提前回款
					dayInvestorPlanInfoDTO.setAdvanceOverdueDays(formatDay(dto.getReceivedDate()));
				}  else {
					dayInvestorPlanInfoDTO.setStatus((byte)4); //4-已按时回款
				}
				
				isOver = true;
				break;
			case 3: //逾期收款
				dayInvestorPlanInfoDTO.setUnreceivedAmount(dto.getReceivedCapital().add(dto.getReceivedInterest()).add(dto.getReceivedPenaltyFee().setScale(2, RoundingMode.HALF_EVEN)));
				receivedAmount = receivedAmount.add(dto.getReceivedCapital()).setScale(2, RoundingMode.HALF_EVEN); //.add(dto.getReceivedInterest()).add(dto.getReceivedPenaltyFee())
				
				// 8-逾期已回款
				dayInvestorPlanInfoDTO.setStatus((byte)8); //8-逾期已回款
				dayInvestorPlanInfoDTO.setAdvanceOverdueDays(formatDay(dto.getReceivedDate()));
				
				isOver = true;
				break;
			case 4: //提前结清收款
				dayInvestorPlanInfoDTO.setUnreceivedAmount(dto.getReceivedCapital().add(dto.getReceivedInterest()).add(dto.getReceivedPenaltyFee().setScale(2, RoundingMode.HALF_EVEN)));
				receivedAmount = receivedAmount.add(dto.getReceivedCapital()).setScale(2, RoundingMode.HALF_EVEN); //.add(dto.getReceivedInterest()).add(dto.getReceivedPenaltyFee())
				
				// 5-已提前结清、9-已结清
				if (dto.getOverTime().before(dto.getReceivedDate())) {
					dayInvestorPlanInfoDTO.setStatus((byte)5); //5-已提前结清
					dayInvestorPlanInfoDTO.setAdvanceOverdueDays(formatDay(dto.getReceivedDate()));
				} else {
					dayInvestorPlanInfoDTO.setStatus((byte)9); //9-已结清
				}
				
				isOver = true;
				break;
			case 5: //已转让
				// 判断是否是债转标的
				if (saleDetails.containsKey(String.valueOf(dto.getInvestOrderId()))) {
					// 计算转让期数 
					CreditorSaleDetail detail = saleDetails.get(String.valueOf(dto.getInvestOrderId()));
					int transferPeriod = detail.getDeadline() - detail.getRemainingDeadlineMonth();
					
					//债转标需要计算当期收益
					if (dayInvestorPlanInfoDTO.getCurrentPeriod() == transferPeriod) {
						dayInvestorPlanInfoDTO.setUnreceivedAmount(detail.getArrivalAmount().add(detail.getExpenseAmount()).setScale(2, RoundingMode.HALF_EVEN));
						receivedAmount = receivedAmount.add(detail.getArrivalAmount()).add(detail.getExpenseAmount()).setScale(2, RoundingMode.HALF_EVEN); //.add(dto.getReceivedInterest()).add(dto.getReceivedPenaltyFee())
					} else {
						dayInvestorPlanInfoDTO.setUnreceivedAmount(new BigDecimal(0));
					}
				}
				
				dayInvestorPlanInfoDTO.setStatus((byte)7); //7-已转让
				
				isOver = true;
				break;
			default:
				continue;
			}
			
			//标的加息
			if (projectRaiseMap.containsKey(String.valueOf(dto.getInvestOrderId())+"_"+String.valueOf(dto.getCurrentPeriod()))) {
				ProjectAddInterestDTO projectRaisePlanDTO = projectRaiseMap.get(String.valueOf(dto.getInvestOrderId())+"_"+String.valueOf(dto.getCurrentPeriod()));
				if (projectRaisePlanDTO != null) {
					dayInvestorPlanInfoDTO.setUnreceivedAmount(dayInvestorPlanInfoDTO.getUnreceivedAmount().add(projectRaisePlanDTO.getExtraAmount()).setScale(2, RoundingMode.HALF_EVEN));
					if (!isOver && projectRaisePlanDTO.getStatus() == 0) { //0：未回款
						unreceivedAmount = unreceivedAmount.add(projectRaisePlanDTO.getExtraAmount()).setScale(2, RoundingMode.HALF_EVEN);
					}
				}
			}
			
			//红包加息或返现
			if (dto.getPrizeId() != null && dto.getPrizeId() > 0) {
				if (projectPrizeMap.containsKey(dto.getPrizeId()+"_"+dto.getProjectId()+"_"+dto.getCurrentPeriod())) {
					ProjectAddInterestDTO projectRaisePlanDTO = projectPrizeMap.get(dto.getPrizeId()+"_"+dto.getProjectId()+"_"+dto.getCurrentPeriod());
					if (projectRaisePlanDTO != null) {
						dayInvestorPlanInfoDTO.setUnreceivedAmount(dayInvestorPlanInfoDTO.getUnreceivedAmount().add(projectRaisePlanDTO.getExtraAmount()).setScale(2, RoundingMode.HALF_EVEN));
						if (!isOver && projectRaisePlanDTO.getStatus() == 0) { //0：未回款
							unreceivedAmount = unreceivedAmount.add(projectRaisePlanDTO.getExtraAmount()).setScale(2, RoundingMode.HALF_EVEN);
						}
					}
				}
			}

			// 判断是否是债转标的
			if (dto.getCreditorSaleDetailId() != null) {
				dayInvestOrderInfoDTO = investOrderMap.get(String.valueOf(dto.getInvestOrderId()));
				dayInvestOrderInfoDTO.getInvestorPlans().add(dayInvestorPlanInfoDTO);
				// 类型， 1-信用标；2-抵押标；3-债转标
				dayInvestOrderInfoDTO.setType((byte) 3);
				continue;
			}
			
			// 智能投
			if (dto.getPackageOrderId() != null) {
				packageOrderMap.get(String.valueOf(dto.getPackageOrderId())).getInvestorPlans().add(dayInvestorPlanInfoDTO);
				continue;
			}
			
			// 3:房抵贷，4:车抵贷
			//if (dto.getLoanType() == LoanTypeEnum.HOUSE_MORTGAGE_LOAN.getValue() 
			//		|| dto.getLoanType() == LoanTypeEnum.VEHICLE_MORTGAGE_LOAN.getValue()) {
			//	dayInvestOrderInfoDTO = investOrderMap.get(String.valueOf(dto.getInvestOrderId()));
			//	dayInvestOrderInfoDTO.getInvestorPlans().add(dayInvestorPlanInfoDTO);
			//	// 类型， 1-信用标；2-抵押标；3-债转标
			//	dayInvestOrderInfoDTO.setType((byte) 2);
			//	continue;
			//}
			
			// 1:社保贷，2:信用卡贷，3:房抵贷，4:车抵贷，5:供应链贷，6:极速贷，9:其它
			dayInvestOrderInfoDTO = investOrderMap.get(String.valueOf(dto.getInvestOrderId()));
			dayInvestOrderInfoDTO.getInvestorPlans().add(dayInvestorPlanInfoDTO);
			// 类型， 1-信用标；2-抵押标；3-债转标
			dayInvestOrderInfoDTO.setType((byte) 1);
		}

		Iterator<DayPackageInfoDTO> it = packageOrderMap.values().iterator();
		DayPackageInfoDTO tmp = null;
		while (it.hasNext()) {
			tmp = it.next();
			if (tmp.getInvestorPlans() != null && !tmp.getInvestorPlans().isEmpty())
				Collections.sort(tmp.getInvestorPlans());
			
			packageOrders.add(tmp);
		}
		
		Iterator<DayInvestOrderInfoDTO> investOrderIt = investOrderMap.values().iterator();
		DayInvestOrderInfoDTO tmpInvestOrder = null;
		while (investOrderIt.hasNext()) {
			tmpInvestOrder = investOrderIt.next();
			if (tmpInvestOrder.getInvestorPlans() != null && !tmpInvestOrder.getInvestorPlans().isEmpty())
				Collections.sort(tmpInvestOrder.getInvestorPlans());
			
			// 类型， 1-信用标；3-债转标
			if (tmpInvestOrder.getType() == 3) {
				debtOrders.add(tmpInvestOrder);
			//} else if (tmpInvestOrder.getType() == 2) {
			//	mortgageLoans.add(tmpInvestOrder);
			} else {
				creditsLoans.add(tmpInvestOrder);
			}
		}
		
		Collections.sort(packageOrders);
		Collections.sort(creditsLoans);
		//Collections.sort(mortgageLoans);
		Collections.sort(debtOrders);
		
		//已收收益
		GroupAmountByDayResponseDTO groupAmountByDayResponseDTO = userBillStatisticsDubboService.groupAmountOneDay(request.getUserId(), dateStrFormat(request.getBeginDate(), "yyyyMMdd"), GroupUserBillAmountTypeEnum.INCOME_RECEIVED);
		if (groupAmountByDayResponseDTO != null && groupAmountByDayResponseDTO.getAmount() != null) {
			receivedAmount = receivedAmount.add(groupAmountByDayResponseDTO.getAmount()).setScale(2, RoundingMode.HALF_EVEN);
		}
		
		result = new DayInvestInfoResponseDTO();
		result.setUnreceivedAmount(unreceivedAmount.setScale(2, RoundingMode.HALF_EVEN));
		result.setReceivedAmount(receivedAmount.setScale(2, RoundingMode.HALF_EVEN));
		result.setNum(list.size());
		result.setReturnedMoneyDate(DateUtils.format(request.getBeginDate(), DateUtils.SHOW_DATE_FORMAT));
		result.setPackageOrders(packageOrders);
		result.setCreditsLoans(creditsLoans);
		//result.setMortgageLoans(mortgageLoans);
		result.setDebtOrders(debtOrders);
		
		return result;
	}

	private String calcAdvanceOverdueDay(Date receivedDate, Integer advanceOverdueDays) {
		if (receivedDate == null) return "";
		
		if (advanceOverdueDays == null) advanceOverdueDays = 0;
		
		DateTime dt = new DateTime(receivedDate);
		dt = dt.plusDays(advanceOverdueDays);
		
		return formatDay(dt.toDate());
	}
	
	private String formatDay(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat("MM月dd日");
		return sdf.format(date);
	}

	@Override
	public List<InvestCalendarMonthStatResponseDTO> monthStat(InvestCalendarRequestDTO request) {
		List<InvestPlanStatDTO> unReceiveList = investCalendarLocalService.findYearEveryMonthUnReceiveInvestPlans(request.getUserId(), request.getBeginDate(), request.getEndDate());
		List<InvestPlanStatDTO> receivedList = investCalendarLocalService.findYearEveryMonthReceivedInvestPlans(request.getUserId(), request.getBeginDate(), request.getEndDate());
		
		Map<String, InvestCalendarMonthStatResponseDTO> map = new HashMap<>();
		
		InvestCalendarMonthStatResponseDTO resDTO = null;
		for (InvestPlanStatDTO dto : unReceiveList) {
			resDTO = new InvestCalendarMonthStatResponseDTO();
			resDTO.setUnreceivedAmount(dto.getCapital().add(dto.getInterest()).subtract(dto.getReceivedCapital()).subtract(dto.getReceivedInterest()).setScale(2, RoundingMode.HALF_EVEN));
			resDTO.setUnreceivedInterest(dto.getInterest().subtract(dto.getReceivedInterest()).setScale(2, RoundingMode.HALF_EVEN));
			resDTO.setUnreceivedPrincipal(dto.getCapital().subtract(dto.getReceivedCapital()).setScale(2, RoundingMode.HALF_EVEN));
			resDTO.setReceivedAmount(dto.getReceivedCapital());
			resDTO.setReceivedInterest(new BigDecimal(0));
			resDTO.setReceivedPrincipal(dto.getReceivedCapital());
			
			String[] sArr = dto.getDay().split("-");
			resDTO.setYear(sArr[0]);
			resDTO.setMonth(sArr[1]);
			
			map.put(dto.getDay(), resDTO);
		}
		
		for (InvestPlanStatDTO dto : receivedList) {
			if (map.containsKey(dto.getDay())) {
				resDTO = map.get(dto.getDay());
				resDTO.setReceivedAmount(dto.getReceivedCapital()); //.add(dto.getReceivedInterest()).add(dto.getPenaltyFee()).setScale(2, RoundingMode.HALF_EVEN)
				resDTO.setReceivedInterest(new BigDecimal(0)); //dto.getReceivedInterest().add(dto.getPenaltyFee())
				resDTO.setReceivedPrincipal(dto.getReceivedCapital());
			} else {
				resDTO = new InvestCalendarMonthStatResponseDTO();
				resDTO.setReceivedAmount(dto.getReceivedCapital()); //.add(dto.getReceivedInterest()).add(dto.getPenaltyFee()).setScale(2, RoundingMode.HALF_EVEN)
				resDTO.setReceivedInterest(new BigDecimal(0)); //dto.getReceivedInterest().add(dto.getPenaltyFee())
				resDTO.setReceivedPrincipal(dto.getReceivedCapital());
				resDTO.setUnreceivedAmount(new BigDecimal(0));
				resDTO.setUnreceivedInterest(new BigDecimal(0));
				resDTO.setUnreceivedPrincipal(new BigDecimal(0));
				
				String[] sArr = dto.getDay().split("-");
				resDTO.setYear(sArr[0]);
				resDTO.setMonth(sArr[1]);

				map.put(dto.getDay(), resDTO);
			}
		}

		Map<String, BigDecimal> raiseAmountMap = calcPeriodUnreceivedRaiseAmount(request.getUserId(), request.getBeginDate(), request.getEndDate(), true);
		String dayKey;
		Iterator<String> dayKeyIterator = raiseAmountMap.keySet().iterator();
		while (dayKeyIterator.hasNext()) {
			dayKey = dayKeyIterator.next();

			if (!map.containsKey(dayKey)) {
				log.info("错误的加息数据， raiseAmount={}", dayKey);
				continue;
			}

			resDTO = map.get(dayKey);
			resDTO.setUnreceivedAmount(resDTO.getUnreceivedAmount().add(raiseAmountMap.get(dayKey)).setScale(2, RoundingMode.HALF_EVEN));
			resDTO.setUnreceivedInterest(resDTO.getUnreceivedInterest().add(raiseAmountMap.get(dayKey)).setScale(2, RoundingMode.HALF_EVEN));
		}

		List<GroupAmountByMonthResponseDTO> list = userBillStatisticsDubboService.groupAmountByMonthForYear(request.getUserId(), dateStrFormat(request.getBeginDate(), "yyyy"), GroupUserBillAmountTypeEnum.INCOME_RECEIVED);
		if (list != null && !list.isEmpty()) {
			for (GroupAmountByMonthResponseDTO tmpDTO : list) {
				if (tmpDTO.getAmount() == null) continue;
				
				resDTO = map.get(dateStrFormat(DateUtils.parseDateFromString(tmpDTO.getMonth(), "yyyyMM"), "yyyy-MM"));
				
				if (resDTO == null) {
					log.info("错误账单统计， bill={}", JSONObject.toJSONString(tmpDTO));
					continue;
				}
				
				resDTO.setReceivedAmount(resDTO.getReceivedAmount().add(tmpDTO.getAmount()).setScale(2, RoundingMode.HALF_EVEN));
				resDTO.setReceivedInterest(resDTO.getReceivedInterest().add(tmpDTO.getAmount()).setScale(2, RoundingMode.HALF_EVEN));
			}
		}
		
		List<InvestCalendarMonthStatResponseDTO> result = new ArrayList<>();
		Iterator<InvestCalendarMonthStatResponseDTO> it = map.values().iterator();
		while (it.hasNext()) {
			result.add(it.next());
		}
		Collections.sort(result);
		
		return result;
	}

	private Map<String, BigDecimal> calcPeriodUnreceivedRaiseAmount(String userId, Date beginDate, Date endDate, boolean isMonthStat) {
		List<DayAllProjectInvestorPlanDTO> planlist = investCalendarLocalService.getUnreceivedProjectInvestorPlans(userId, beginDate, endDate);

		Map<String, DayAllProjectInvestorPlanDTO> projectPeriodAmount = new HashMap<>();

		List<ProjectRaisePlanReqDTO> raiseList = new ArrayList<>();
		List<ProjectPrizeReqDTO> prizeList = new ArrayList<>();

		ProjectRaisePlanReqDTO projectRaisePlanReqDTO = null;
		ProjectPrizeReqDTO projectPrizeReqDTO = null;

		// 封装要查询的标的加息和红包加息参数列表
		for (DayAllProjectInvestorPlanDTO plan : planlist) {
			if (plan.getPrizeId() != null && plan.getPrizeId() > 0) {
				projectPrizeReqDTO = new ProjectPrizeReqDTO();
				projectPrizeReqDTO.setProjectId(plan.getProjectId());
				projectPrizeReqDTO.setPrizeId(plan.getPrizeId());
				projectPrizeReqDTO.setCurrentPeriod(plan.getCurrentPeriod());

				prizeList.add(projectPrizeReqDTO);
			}
			projectRaisePlanReqDTO = new ProjectRaisePlanReqDTO();
			projectRaisePlanReqDTO.setInvestOrderId(plan.getInvestOrderId());
			projectRaisePlanReqDTO.setCurrentPeriod(plan.getCurrentPeriod());

			raiseList.add(projectRaisePlanReqDTO);

			projectPeriodAmount.put(String.valueOf(plan.getInvestOrderId())+"_"+String.valueOf(plan.getCurrentPeriod()), plan);
		}

		DayAllProjectInvestorPlanDTO tmp = null;

		//标的加息
		ProjectRaiseAddInterestReqDTO reqDTO = new ProjectRaiseAddInterestReqDTO();
		reqDTO.setUserId(userId);
		reqDTO.setInvestOrderList(raiseList);
		ProjectAddInterestSummarizeRespDTO projectAddInterestSummarizeRespDTO = activityPrizeDubboService.findProjectRaiseAddInterestInfo(reqDTO);
		if (projectAddInterestSummarizeRespDTO != null && projectAddInterestSummarizeRespDTO.getDetails() != null) {
			for (ProjectAddInterestDTO projectRaisePlanDTO : projectAddInterestSummarizeRespDTO.getDetails()) {
				if (projectRaisePlanDTO.getExtraAmount() == null) continue;

				tmp = projectPeriodAmount.get(String.valueOf(projectRaisePlanDTO.getInvestOrderId())+"_"+String.valueOf(projectRaisePlanDTO.getCurrentPeriod()));

				if (tmp == null) continue;
				tmp.setUnreceivedRaiseAmount(tmp.getUnreceivedRaiseAmount().add(projectRaisePlanDTO.getExtraAmount()).setScale(2, RoundingMode.HALF_EVEN));
			}
		}

		//投资加息
		PrizeAddInterestReqDTO prizeReqDTO = new PrizeAddInterestReqDTO();
		prizeReqDTO.setUserId(userId);
		prizeReqDTO.setProjectPrizeList(prizeList);
		projectAddInterestSummarizeRespDTO = activityPrizeDubboService.findProjectPrizeAddInterestInfo(prizeReqDTO);
		if (projectAddInterestSummarizeRespDTO != null && projectAddInterestSummarizeRespDTO.getDetails() != null) {
			for (ProjectAddInterestDTO projectRaisePlanDTO : projectAddInterestSummarizeRespDTO.getDetails()) {
				if (projectRaisePlanDTO.getExtraAmount() == null) continue;

				tmp = projectPeriodAmount.get(String.valueOf(projectRaisePlanDTO.getInvestOrderId())+"_"+String.valueOf(projectRaisePlanDTO.getCurrentPeriod()));

				if (tmp == null) continue;
				tmp.setUnreceivedRaiseAmount(tmp.getUnreceivedRaiseAmount().add(projectRaisePlanDTO.getExtraAmount()).setScale(2, RoundingMode.HALF_EVEN));
			}
		}

		Map<String, BigDecimal> result = new HashMap<>();
		Iterator<DayAllProjectInvestorPlanDTO> it = projectPeriodAmount.values().iterator();
		while (it.hasNext()) {
			tmp = it.next();

			if (isMonthStat) { //月统计
				result.put(DateUtils.format(tmp.getReceivedDate(), "yyyy-MM"), tmp.getUnreceivedRaiseAmount());
			} else { //日统计
				result.put(DateUtils.format(tmp.getReceivedDate(), DateUtils.SHOW_DATE_FORMAT), tmp.getUnreceivedRaiseAmount());
			}
		}

		return result;
	}
	
	private String dateStrFormat(Date date, String formatStr) {
		SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
		return sdf.format(date);
	}

	@Override
	public List<InvestCalendarDayStatResponseDTO> dayStat(InvestCalendarRequestDTO request) {
		List<InvestPlanStatDTO> unReceiveList = investCalendarLocalService.findMonthEveryDayUnReceiveInvestPlans(request.getUserId(), request.getBeginDate(), request.getEndDate());
		List<InvestPlanStatDTO> receivedList = investCalendarLocalService.findMonthEveryDayReceivedInvestPlans(request.getUserId(), request.getBeginDate(), request.getEndDate());
		
		Map<String, InvestCalendarDayStatResponseDTO> map = new HashMap<>();
		
		InvestCalendarDayStatResponseDTO resDTO = null;
		for (InvestPlanStatDTO dto : unReceiveList) {
			resDTO = new InvestCalendarDayStatResponseDTO();
			resDTO.setUnreceivedAmount(dto.getCapital().add(dto.getInterest()).subtract(dto.getReceivedCapital()).subtract(dto.getReceivedInterest()).setScale(2, RoundingMode.HALF_EVEN));
			resDTO.setUnreceivedInterest(dto.getInterest().subtract(dto.getReceivedInterest()).setScale(2, RoundingMode.HALF_EVEN));
			resDTO.setUnreceivedPrincipal(dto.getCapital().subtract(dto.getReceivedCapital()).setScale(2, RoundingMode.HALF_EVEN));
			resDTO.setReceivedAmount(dto.getReceivedCapital());
			resDTO.setReceivedInterest(new BigDecimal(0));
			resDTO.setReceivedPrincipal(dto.getReceivedCapital());
			
			String[] sArr = dto.getDay().split("-");
			resDTO.setYear(sArr[0]);
			resDTO.setMonth(sArr[1]);
			resDTO.setDay(sArr[2]);
			
			map.put(dto.getDay(), resDTO);
		}
		
		for (InvestPlanStatDTO dto : receivedList) {
			if (map.containsKey(dto.getDay())) {
				resDTO = map.get(dto.getDay());
				resDTO.setReceivedAmount(dto.getReceivedCapital()); //.add(dto.getReceivedInterest()).add(dto.getPenaltyFee()).setScale(2, RoundingMode.HALF_EVEN)
				resDTO.setReceivedInterest(new BigDecimal(0)); //dto.getReceivedInterest().add(dto.getPenaltyFee())
				resDTO.setReceivedPrincipal(dto.getReceivedCapital());
			} else {
				resDTO = new InvestCalendarDayStatResponseDTO();
				resDTO.setReceivedAmount(dto.getReceivedCapital()); //.add(dto.getReceivedInterest()).add(dto.getPenaltyFee()).setScale(2, RoundingMode.HALF_EVEN)
				resDTO.setReceivedInterest(new BigDecimal(0)); //dto.getReceivedInterest().add(dto.getPenaltyFee())
				resDTO.setReceivedPrincipal(dto.getReceivedCapital());
				resDTO.setUnreceivedAmount(new BigDecimal(0));
				resDTO.setUnreceivedInterest(new BigDecimal(0));
				resDTO.setUnreceivedPrincipal(new BigDecimal(0));
				
				String[] sArr = dto.getDay().split("-");
				resDTO.setYear(sArr[0]);
				resDTO.setMonth(sArr[1]);
				resDTO.setDay(sArr[2]);

				map.put(dto.getDay(), resDTO);
			}
		}

		Map<String, BigDecimal> raiseAmountMap = calcPeriodUnreceivedRaiseAmount(request.getUserId(), request.getBeginDate(), request.getEndDate(), false);
		String dayKey;
		Iterator<String> dayKeyIterator = raiseAmountMap.keySet().iterator();
		while (dayKeyIterator.hasNext()) {
			dayKey = dayKeyIterator.next();

			if (!map.containsKey(dayKey)) {
				log.info("错误的加息数据， raiseAmount={}", dayKey);
				continue;
			}

			resDTO = map.get(dayKey);
			resDTO.setUnreceivedAmount(resDTO.getUnreceivedAmount().add(raiseAmountMap.get(dayKey)).setScale(2, RoundingMode.HALF_EVEN));
			resDTO.setUnreceivedInterest(resDTO.getUnreceivedInterest().add(raiseAmountMap.get(dayKey)).setScale(2, RoundingMode.HALF_EVEN));
		}
		
		List<GroupAmountByDayResponseDTO> list = userBillStatisticsDubboService.groupAmountByDayForMonth(request.getUserId(), dateStrFormat(request.getBeginDate(), "yyyyMM"), GroupUserBillAmountTypeEnum.INCOME_RECEIVED);
		if (list != null && !list.isEmpty()) {
			for (GroupAmountByDayResponseDTO tmpDTO : list) {
				if (tmpDTO.getAmount() == null) continue;
				
				resDTO = map.get(dateStrFormat(DateUtils.parseDateFromString(tmpDTO.getDay(), "yyyyMMdd"), "yyyy-MM-dd"));
				if (resDTO == null) {
					log.info("错误账单统计， bill={}", JSONObject.toJSONString(tmpDTO));
					continue;
				}
				
				resDTO.setReceivedAmount(resDTO.getReceivedAmount().add(tmpDTO.getAmount()).setScale(2, RoundingMode.HALF_EVEN));
				resDTO.setReceivedInterest(resDTO.getReceivedInterest().add(tmpDTO.getAmount()).setScale(2, RoundingMode.HALF_EVEN));
			}
		}
		
		List<InvestCalendarDayStatResponseDTO> result = new ArrayList<>();
		Iterator<InvestCalendarDayStatResponseDTO> it = map.values().iterator();
		while (it.hasNext()) {
			result.add(it.next());
		}
		
		Collections.sort(result);
		
		return result;
	}

}
